home *** CD-ROM | disk | FTP | other *** search
- ' BOWLING.BAS
- ' This program uses random numbers to simulate a 10-frame bowling game.
-
- ' declare subprograms and function
-
- DECLARE SUB ScoreCard ()
- DECLARE SUB Pause ()
- DECLARE FUNCTION GetRandBowl% (values%)
- DECLARE SUB ShowBowl (value%)
- DECLARE SUB DrawPins (pins%)
- DECLARE SUB ProcessSpare (extraBall%, offset%)
- DECLARE SUB TenthFrameStrike ()
- DECLARE SUB TenthFrameSpare ()
-
- ' declare global variables and constants
-
- COMMON SHARED total%, strike%, spare%, score$
- CONST FRAMEROW% = 3: CONST SCOREROW% = 5
- CONST FALSE% = 0, TRUE% = NOT FALSE%
-
- RANDOMIZE TIMER ' seed random number generator with system clock
- score$ = "###" ' template for displaying total% with PRINT USING
-
- CLS
-
- ScoreCard ' call ScoreCard to display frames and gutters
- DrawPins 10 ' set a fresh rack of 10 pins to start game
-
- FOR i% = 1 TO 10 ' for each of the 10 frames...
- Pause ' pause the action
- DrawPins 10 ' set a fresh rack of 10 pins
-
- firstBowl% = GetRandBowl%(10) ' get random number for first ball
- strikeDelay% = TRUE% ' set "strike" flag to true
-
- IF (firstBowl% = 10) THEN ' if first ball is a strike...
- ShowBowl 10 ' show a throw that gets 10 pins
- DrawPins 0 ' show an empty lane
- LOCATE FRAMEROW%, 3 + ((i% - 1) * 6) ' use i% to locate frame
- PRINT "X" ' ...and print "X" for strike
- pinsDown% = 10 ' set pinsDown% count to 10
- strike% = strike% + 1 ' increment the number of strikes
- noStrikes% = FALSE% ' set "no strike" flag to false
-
- ' if 3 strikes have been bowled, set flag to process the first
- IF (strike% = 3) THEN strikeDelay% = TRUE% ELSE strikeDelay% = FALSE%
-
- ' if working on a spare, calculate score for last frame
- IF (spare%) THEN ProcessSpare firstBowl%, i%
-
- ELSE ' if first throw was not a strike...
- ShowBowl firstBowl% ' show an appropriate throw
- DrawPins 10 - firstBowl% ' draw the remaining pins
- LOCATE FRAMEROW%, 2 + ((i% - 1) * 6) ' use i% to locate frame
- PRINT firstBowl% ' ...and display first ball
-
- ' if working on a spare, calculate score for last frame
- IF (spare%) THEN ProcessSpare firstBowl%, i%
-
- Pause ' pause the action
-
- ' get random number for second ball
- secondBowl% = GetRandBowl%(10 - firstBowl%)
- ShowBowl firstBowl% + secondBowl% ' show the ball
- DrawPins 10 - (firstBowl% + secondBowl%) ' draw remainder
-
- pinsDown% = firstBowl% + secondBowl% ' add up pins
- noStrikes% = TRUE% ' set "no strike" flag to true
- IF (pinsDown% = 10) THEN ' if two balls make a spare...
- LOCATE FRAMEROW%, 5 + ((i% - 1) * 6) ' locate frame
- PRINT "/" ' ...and print "/" for spare
- spare% = TRUE% ' set "spare" flag to true
- ELSE ' if not a spare...
- LOCATE FRAMEROW%, 4 + ((i% - 1) * 6) ' locate frame
- PRINT secondBowl% ' ...and display second ball
- END IF
- END IF
-
- ' process outstanding strikes if bonus balls are available
-
- IF (strike% >= 1) AND (strikeDelay%) THEN
-
- IF (strike% = 1) THEN ' if single strike
- total% = total% + 10 + firstBowl% + secondBowl%
- LOCATE SCOREROW%, 3 + ((i% - 2) * 6) ' locate last frame
- PRINT USING score$; total% ' print total score
- strikeDelay% = FALSE% ' set "strike" flag to false
- END IF
-
- IF (strike% = 2) OR (strike% = 3) THEN ' if double or triple
- total% = total% + 10 + 10 + firstBowl% ' total pins
- LOCATE SCOREROW%, 3 + ((i% - 3) * 6) ' move 2 frames back
- PRINT USING score$; total% ' print total score
- IF (noStrikes%) THEN ' if all bonus balls available
- total% = total% + 10 + firstBowl% + secondBowl%
- LOCATE SCOREROW%, 3 + ((i% - 2) * 6) ' get last frame
- PRINT USING score$; total% ' print total score
- strike% = 0 ' set number of
- END IF ' strikes to zero
- END IF
-
- strike% = strike% - 1 ' decrement number of strikes
- IF (strike% < 0) THEN strike% = FALSE% ' don't go below zero
- END IF
-
- IF (pinsDown% < 10) AND (NOT strike%) THEN ' calculate pin total
- total% = total% + pinsDown% ' for open frame
- LOCATE SCOREROW%, 3 + ((i% - 1) * 6) ' and display score
- PRINT USING score$; total%
- END IF
-
- NEXT i%
-
- IF (strike%) THEN TenthFrameStrike ' if a strike in the 10th frame
-
- IF (spare%) THEN TenthFrameSpare ' if a spare in the 10th frame
-
- END ' end main program
-
- SUB DrawPins (num%)
-
- ' DrawPins displays the number of pins specified by num%.
- ' CHR$(173) is an upside-down exclamation mark from the
- ' IBM extended character set used to represent a pin.
-
- COLOR 14 ' set color to yellow
-
- LOCATE 21, 70 ' this is the last pin to be knocked down
- IF (num% = 10) THEN PRINT CHR$(173) ELSE PRINT " "
-
- LOCATE 20, 68
- IF (num% >= 9) THEN PRINT CHR$(173) ELSE PRINT " "
-
- LOCATE 19, 66
- IF (num% >= 8) THEN PRINT CHR$(173) ELSE PRINT " "
-
- LOCATE 19, 70
- IF (num% >= 7) THEN PRINT CHR$(173) ELSE PRINT " "
-
- LOCATE 18, 68
- IF (num% >= 6) THEN PRINT CHR$(173) ELSE PRINT " "
-
- LOCATE 18, 64
- IF (num% >= 5) THEN PRINT CHR$(173) ELSE PRINT " "
-
- LOCATE 17, 66
- IF (num% >= 4) THEN PRINT CHR$(173) ELSE PRINT " "
-
- LOCATE 16, 68
- IF (num% >= 3) THEN PRINT CHR$(173) ELSE PRINT " "
-
- LOCATE 17, 70
- IF (num% >= 2) THEN PRINT CHR$(173) ELSE PRINT " "
-
- LOCATE 15, 70 ' this is the first pin to be knocked down
- IF (num% >= 1) THEN PRINT CHR$(173) ELSE PRINT " "
-
- COLOR 7 ' set color back to white
-
- END SUB
-
- FUNCTION GetRandBowl% (values%)
-
- ' GetRandBowl% returns a random number between 1 and values% to
- ' the calling procedure.
-
- GetRandBowl% = INT(RND * (values% + 1))
-
- END FUNCTION
-
- SUB Pause
-
- ' Pause returns the ball to the top of the lane and pauses the action.
-
- FOR ballPos% = 68 TO 3 STEP -1 ' return ball to top of lane
- SOUND 150, .1 ' play appropriate sound
- LOCATE 12, ballPos%: PRINT CHR$(2) ' ball is ASCII code number 2
- SOUND 160, .1
- LOCATE 12, ballPos% + 1: PRINT " "
- SOUND 1170, .1
- NEXT ballPos%
-
- LOCATE 8, 1
- COLOR 14, 1 ' set color to yellow-on-blue
- INPUT "Press Enter to bowl ", dummy$ ' pause the action
- COLOR 7, 0 ' return color to defaults
-
- LOCATE 12, 3: PRINT " " ' hide resting place of ball
-
- END SUB
-
- SUB ProcessSpare (extraBall%, offset%)
-
- ' ProcessSpare calculates the score for the preceeding frame when
- ' the extra ball is available. Offset% is the frame location.
-
- total% = total% + 10 + extraBall% ' calculate frame score
- LOCATE SCOREROW%, 3 + ((offset% - 2) * 6) ' use offset% to get frame
- PRINT USING score$; total% ' display the total
- spare% = FALSE% ' set "spare" switch to false
-
- END SUB
-
- SUB ScoreCard
-
- ' ScoreCard displays the bowling scorecard and the alley gutters.
-
- COLOR 3 ' set foreground color to cyan
-
- PRINT " 1 2 3 4 5 6 7 8 9 10"
- PRINT STRING$(63, "-")
- PRINT "| | | | | | | | | | |"
- PRINT "| | | | | | | | | | |"
- PRINT "| | | | | | | | | | |"
- PRINT STRING$(63, "-")
-
- LOCATE 13, 5
- PRINT STRING$(66, "-")
- LOCATE 23, 5
- PRINT STRING$(66, "-")
-
- COLOR 7 ' set foreground color to white
-
- END SUB
-
- SUB ShowBowl (pins%)
-
- ' ShowBowl shows the ball rolling down the lane through the pins
- ' with appropriate sounds. The pins% parameter represents the
- ' number of pins that should fall and is used to send the ball
- ' in the right direction.
-
- LOCATE 8, 1 ' cover up the "Press Enter" message
- PRINT SPACE$(20)
-
- value% = (pins% + 1) \ 2 ' set target range
- IF (value% < 3) AND (value% >= 0) THEN value% = value% + 1
- row% = 18 ' set starting row
-
- FOR i% = 2 TO 68 STEP 10 ' roll ball down lane
- FOR j% = 1 TO 10
- SOUND 63, .2 ' play appropriate sound
- LOCATE row%, i% - 1 + j%: PRINT " " ' cover up tracks
-
- IF (i% > 54) AND (row% <= 18) THEN ' change sound when in
- FOR k% = 1 TO 5 ' the pins
- note% = INT(RND(1) * 150): SOUND 50 + note%, .1
- NEXT k%
- END IF
-
- IF (i% > 61) AND (row% >= 19) AND (row <= 21) THEN
- FOR k% = 1 TO 5
- note% = INT(RND(1) * 150): SOUND 50 + note%, .1
- NEXT k%
- END IF
-
- SOUND 68, .2
- LOCATE row%, i% + j%: PRINT CHR$(2) ' display ball
- SOUND 65, .2
- NEXT j%
-
- LOCATE row%, i% - 1 + j%: PRINT " " ' cover up tracks
- IF (value% >= 5) THEN row% = row% - 1
- row% = row% + 1: value% = value% + 1 ' move to next row
- NEXT i%
-
- END SUB
-
- SUB TenthFrameSpare
-
- ' TenthFrameSpare handles the throwing of another ball and the
- ' calculation of the 10th frame if there is a spare in the 10th.
-
- Pause ' pause for extra ball
- DrawPins 10 ' set up a fresh rack of 10 pins
- firstBowl% = GetRandBowl%(10) ' get a random number for extra ball
- ShowBowl firstBowl% ' show the ball rolling down the alley
- DrawPins 10 - firstBowl% ' take away the pins that fell
-
- IF (firstBowl% = 10) THEN ' if the extra ball is a 10 then
- LOCATE FRAMEROW%, 61 ' locate the extra slot
- PRINT "X" ' and display an "X" for strike
- ELSE
- LOCATE FRAMEROW%, 60 ' if the extra ball is not 10 then
- PRINT firstBowl% ' print its value in extra slot
- END IF
-
- ProcessSpare firstBowl%, 11 ' calculate the final value of the
- ' 10th frame
- END SUB
-
- SUB TenthFrameStrike
-
- ' TenthFrameStrike handles the throwing of two extra balls and any
- ' unresolved frames if a strike is bowled in the 10th frame.
-
- Pause ' pause for first ball
- DrawPins 10 ' set up a fresh rack of 10 pins
- firstBowl% = GetRandBowl%(10) ' get random number for first ball
- ShowBowl firstBowl% ' show the ball rolling down the alley
- DrawPins 10 - firstBowl% ' take away the pins that fell
-
- IF (firstBowl% = 10) THEN ' if the first ball is a 10 then
- LOCATE FRAMEROW%, 59 ' locate the second slot
- PRINT "X" ' and display an "X" for strike
-
- IF (strike% = 2) THEN ' if working on a double,
- total% = total% + 10 + 10 + firstBowl% ' get last frame total
- LOCATE SCOREROW%, 3 + (8 * 6) ' locate last frame
- PRINT USING score$; total% ' record frame score
- END IF
-
- Pause ' pause for second ball
- DrawPins 10 ' set up a fresh rack of 10 pins
- secondBowl% = GetRandBowl%(10) ' get a random number for ball
- ShowBowl secondBowl% ' show the ball rolling down the alley
- DrawPins 10 - secondBowl% ' take away the pins that fell
- IF (secondBowl% = 10) THEN ' if this ball is also a 10,
- LOCATE FRAMEROW%, 61 ' locate the extra slot
- PRINT "X" ' and display an "X" for strike
- ELSE
- LOCATE FRAMEROW%, 60 ' if the ball is not 10 then
- PRINT secondBowl% ' print its value in extra slot
- END IF
- ELSE ' if the first ball is not a 10,
- IF (strike% = 2) THEN ' process the remaining double (if any)
- total% = total% + 10 + 10 + firstBowl% ' get last frame total
- LOCATE SCOREROW%, 3 + (8 * 6) ' locate last frame
- PRINT USING score$; total% ' display frame score
- END IF
-
- secondBowl% = GetRandBowl%(10 - firstBowl%) ' get second ball
- ShowBowl secondBowl% + firstBowl% ' show ball
- DrawPins 10 - (secondBowl% + firstBowl%) ' draw remaining pins
- LOCATE FRAMEROW%, 58
- PRINT firstBowl% ' display first ball
- IF (secondBowl% + firstBowl% = 10) THEN ' if 10 down then
- LOCATE FRAMEROW%, 61 ' print a "/" for
- PRINT "/" ' spare
- ELSE
- LOCATE FRAMEROW%, 60 ' if less than 10,
- PRINT secondBowl% ' print the number
- END IF
- END IF
-
- total% = total% + 10 + firstBowl% + secondBowl% ' calculate and
- LOCATE SCOREROW%, 57 ' display final frame
- PRINT USING score$; total%
-
- END SUB
-
-